package hyl.base.net.bio;

import java.io.IOException;

import hyl.base.net.IData1;
import hyl.core.MyFun;

/**
 * 最底层的数据包基于TCP
 * 
 * @author 37798955@qq.com
 *
 */
public class BIOData1 implements IData1 <byte[]>{


	//0:未知(可以丢弃); 1:消息; 2:命令
	
	byte i类型=B类型_未知;
	byte[] data;

	public byte[] getSendBytes() {
		return MyFun.concat(new byte[] {i类型},MyFun.int2ByteArray(data.length), data);
	}

	public byte getB类型() {
		return i类型;
	}

	public void setI类型(byte i类型) {
		this.i类型 = i类型;
	}

	public byte[] getData() {
		return data;
	}

	public void setData(byte[] 数据) {
		if (数据 == null)
			return;
		this.data = 数据;	
	}
	// -1表示头部未读取,0 表示头部读取完毕, n 表示读取了多少个字节

	//////////////////////////////////////////////////////////////从流中读取数据/////////////////////////
	void reset() {
		i类型=B类型_未知;
		idatalen = 0;	
		已经读取字节 = null;
		headbytes = new byte[4];
		data=null;
	}
	
	int idatalen = 0;
	byte[] 已经读取字节 = null;
	byte[] headbytes = new byte[4];// 头长度
	/**
	 * 
	 * @param br
	 * @return 返回false 表示 该socket已经关闭,已经无效;  返回true 表示socket 可以继续使用
	 * @throws IOException
	 */
	public boolean addData(BIOReader br) throws IOException {
		// 第一个是类型
		
		i类型 =(byte)br._reader.read();
	
		if (i类型 <=IData1.B类型_未知 || i类型>= IData1.B类型_断开) {
			br.close();
			reset() ;
			return false;
		}	
		
		// 第二个是长度
		if (br._reader.read(headbytes) == 4) {			
			idatalen = MyFun.byteArray2Int(headbytes);
		
		}
		if (idatalen<0) {
			br.close();
			reset() ;
			return false;
		}
		// 第三步插入数据
		if (idatalen < BUFSIZE) {
			// 如果数据小于缓冲区 一次性写入
			data = new byte[idatalen];
			br._reader.read(data);
		
		} else {
			// 如果数据大于缓冲区 分多次写入
			int nRead1 = 0;
			已经读取字节 = new byte[BUFSIZE];
			int i插入位置 =0;
			while ((nRead1 = br._reader.read(已经读取字节)) != -1) {
				MyFun.insert(已经读取字节, data, i插入位置);
				i插入位置 += nRead1;
				// 如果全部捕捉到 就
				if (i插入位置 == idatalen)
					break;
				if (i插入位置 + BUFSIZE > idatalen)
					已经读取字节 = new byte[idatalen - i插入位置];
			}
		}
		return true;
	}
	
}
